package org.zebra.mybatis.plus.ext.audit.impl;

import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.select.AllColumns;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.zebra.mybatis.plus.ext.audit.DataAudit;
import org.zebra.mybatis.plus.ext.audit.OperationResult;

import java.sql.Connection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

/**
 * @author zhanghongbin
 */
public class DeleteDataAudit extends DataAudit {

    private int batchUpdateLimit;
    private boolean batchUpdateLimitationOpened;
    private Map<String, Integer> batchUpdateLimitMap;
    private Delete deleteStmt;
    private MappedStatement mappedStatement;
    private BoundSql boundSql;
    private Connection connection;
    private TableInfo tableInfo;
    private Map<String, Set<String>> ignoredTableColumns;

    public DeleteDataAudit(
            Map<String, Set<String>> ignoredTableColumns,
            int batchUpdateLimit,
            boolean batchUpdateLimitationOpened,
            Map<String, Integer> batchUpdateLimitMap,
            Delete deleteStmt,
            MappedStatement mappedStatement,
            BoundSql boundSql,
            Connection connection,
            TableInfo tableInfo) {
        this.ignoredTableColumns = ignoredTableColumns;
        this.batchUpdateLimit = batchUpdateLimit;
        this.batchUpdateLimitationOpened = batchUpdateLimitationOpened;
        this.batchUpdateLimitMap = batchUpdateLimitMap;
        this.deleteStmt = deleteStmt;
        this.mappedStatement = mappedStatement;
        this.boundSql = boundSql;
        this.connection = connection;
        this.tableInfo = tableInfo;
    }

    @Override
    public OperationResult process() {
        Table table = deleteStmt.getTable();
        Expression where = deleteStmt.getWhere();
        Select selectStmt = new Select();
        PlainSelect selectBody = new PlainSelect();
        selectBody.setFromItem(table);
        selectBody.setSelectItems(Collections.singletonList(new AllColumns()));
        selectBody.setWhere(where);
        selectStmt.setSelectBody(selectBody);
        // 表逻辑删除列名
        String logicDeleteColumnName = "";
        if (this.tableInfo != null) {
            String logicDeleteFiledName = this.getLogicDeleteFieldName(this.tableInfo.getEntityType());
            if (!logicDeleteFiledName.isEmpty()) {
                logicDeleteColumnName = StringUtils.camelToUnderline(logicDeleteFiledName);
            }
        }
        String originalData = this.buildOriginalData(
                this.batchUpdateLimit,
                this.batchUpdateLimitationOpened,
                this.batchUpdateLimitMap,
                selectStmt,
                mappedStatement,
                boundSql,
                connection,
                logicDeleteColumnName);
        OperationResult result = new OperationResult();
        result.setOperation("delete");
        result.setTableName(table.getFullyQualifiedName());
        result.setRecordStatus(originalData.startsWith("["));
        result.setChangedData(originalData);
        return result;
    }
}
